package com.ssl;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.SSLEngine;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.ByteOrder;

@Slf4j
public class SecureChatClientInitializer extends ChannelInitializer<SocketChannel> {
    // 反射设置ssl连接超时时间为-1，即不超时，仅用于调试
    public static SslHandler noTimeoutSslHandler(SSLEngine engine) {
        SslHandler sslHandler = new SslHandler(engine);
        try {
            Field handshakeTimeoutMillis = SslHandler.class.getDeclaredField("handshakeTimeoutMillis");
            handshakeTimeoutMillis.setAccessible(true);
            handshakeTimeoutMillis.set(sslHandler, -1L);
            handshakeTimeoutMillis.setAccessible(false);
        } catch (Exception e) {
            log.error("SslHandler.handshakeTimeoutMillis 反射设置失败", e);
        }
        return sslHandler;
    }
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        InputStream jksIs = getClass().getClassLoader().getResourceAsStream("keys/cChat.jks");

        SSLEngine engine = SecureChatSslContextFactory.getClientContext(jksIs)
                .createSSLEngine();//创建SSLEngine
        engine.setUseClientMode(true);//客户方模式
        pipeline.addLast(new LoggingHandler(LogLevel.DEBUG));
        // handshakeTimeoutMillis


        pipeline.addLast("ssl", noTimeoutSslHandler(engine));


        pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        // pipeline.addLast(new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2, true));

        // pipeline.addLast("decoder", new JsonDecoder());
        // pipeline.addLast("encoder", new StringEncoder());
        //pipeline.addLast(new JsonDecoder());
        //pipeline.addLast(new LengthFieldPrepender(2));
        pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
        //pipeline.addLast(new JsonEncoder());

        pipeline.addLast("handler", new SecureChatClientHandler());

    }

    /*public static void main(String[] args) {
        String s=System.getProperty("user.dir")+"\\src\\main\\resources\\cChat.jks";
        System.out.println(s);
    }*/
}